import java.io.File;
import java.io.IOException;
import java.util.Locale;
import java.util.Scanner;
import java.util.Vector;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.WorkbookSettings;
import jxl.read.biff.BiffException;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;


//@author A0099655J
public class Logger {

	public String filename;
	File _file;
	
	/**
	 * @param args
	 * @throws IOException 
	 * @throws BiffException 
	 * @throws WriteException 
	 * @throws RowsExceededException 
	 */

	//@author A0099655J
	// Constructor
	public Logger(String filename) {
		this.filename = filename;
		this._file = checkIfFileExists(this.filename);
		
		assert _file.exists();
	}

	//@author A0099655J
	public File checkIfFileExists(String filename) {
		File f = new File(this.filename);
		if (!f.exists()) {
			try {
				f.createNewFile();
				System.out.println(filename + " created successfully.");
			} catch (IOException e) {
				// returns error while creating file
				e.printStackTrace();
			}
		}
		
		return f;
	}

	//@author A0099655J
	public Vector<LogEntry> read() {
		
		Workbook w1 = null;
		Vector<LogEntry> contents = new Vector<LogEntry>();
		
			try {
				w1 = Workbook.getWorkbook(this._file);
			
			Sheet sheet = w1.getSheet(0);
			
			int rows = sheet.getRows();
			//System.out.println("i:"+rows);
			
			DateTimeFormatter formatter = DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss");
			
			for (int i=1; i<rows; i++) {
				
				String timestamp_str = sheet.getCell(0,i).getContents();
				
				DateTime timestamp_DT = formatter.parseDateTime(timestamp_str);
				
				String operation = sheet.getCell(1,i).getContents();
				TaskList tasks = new TaskList();
				
				Cell[] thisRow = sheet.getRow(i);
				int numColumns = thisRow.length;
				
				//int numColumns = sheet.getColumns();
				for (int j=2; j<numColumns; j+=4) {
					boolean completed = Boolean.parseBoolean(sheet.getCell(j,i).getContents());
					String deadline_str = sheet.getCell(j+1,i).getContents();
					

					//System.out.println(j+1+" "+i+" :"+deadline_str+":");
					if (deadline_str.equals("")) { 
						break; 
					}
					
					DateTime deadline_DT = formatter.parseDateTime(deadline_str);
					String desc = sheet.getCell(j+2,i).getContents();
					
					Task tempTask = new Task(desc, deadline_DT, completed);
					tasks.addTask(tempTask);
				}
				
				LogEntry temp = new LogEntry(timestamp_DT, operation, tasks);
				contents.add(temp);
				
				// For debugging
				//System.out.println("row "+i+": "+dueYear+" "+dueMonth+" "+dueDate+" "+dueHour+" "+desc);		
			}
			
			} catch (BiffException | IOException e) {
				e.printStackTrace();
			}
		return contents;
	}

	//@author A0099655J
	public void write(Vector<LogEntry> contents) {
		Scanner sc2 = new Scanner(System.in);
		
		// Initialise workbook
		WorkbookSettings ws = new WorkbookSettings();
	    ws.setLocale(new Locale("en", "EN"));
	    WritableWorkbook workbook;
		try {
			workbook = Workbook.createWorkbook(new File(filename), ws);
			
		   
		    // Initialise first sheet in workbook
			WritableSheet sheet = workbook.createSheet("Storage", 0);
					
			// set Text format
			WritableCellFormat wrappedText = new WritableCellFormat(WritableWorkbook.ARIAL_10_PT);
			wrappedText.setWrap(true);
		    
			// set headings
			Label l = new Label(0,0, "Timestamp", wrappedText);
			sheet.addCell(l);
			l = new Label(1,0, "Operation", wrappedText);
			sheet.addCell(l);
			l = new Label(2,0, "Completed?", wrappedText);
			sheet.addCell(l);
			l = new Label(3,0, "Start Time", wrappedText);
			sheet.addCell(l);
			l = new Label(4,0, "End Time/Deadline", wrappedText);
			sheet.addCell(l);
			l = new Label(5,0, "Description", wrappedText);
			sheet.addCell(l);
			
			for (int i=0; i < contents.size(); i++) {
				LogEntry currentEntry = contents.get(i);
				String timestamp_str = currentEntry.getTimestampAsString();
				String operation = currentEntry.getCmd();
				
				sheet = writeLogDataToSheet(sheet, wrappedText, i+1, timestamp_str, operation);
				
				int numTasks = currentEntry.getNumTasks();
				Vector<Task> tasks = currentEntry.getTasks().toVector();
				
				for (int j=0; j < numTasks; j++) {
					Task currentTask = tasks.get(j);
					
					boolean completed = currentTask.getStatus();
					DateTime startDateTime_DT = currentTask.getStartDateTime();
					DateTime endDateTime_DT = currentTask.getEndDateTime();
					String desc = currentTask.getDescription();
					
					DateTimeFormatter formatter = DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss");
					String startDateTime_str = startDateTime_DT.toString(formatter);
					String endDateTime_str = endDateTime_DT.toString(formatter);
					
					sheet = writeTasksToSheet(sheet, wrappedText, i+1, 4*j+2, completed, startDateTime_str, endDateTime_str, desc);
					
				}	
			}
	
		workbook.write();
		workbook.close();
		
		} catch (IOException | WriteException e) {
			e.printStackTrace();
		}	
		sc2.close();
	}
	

	//@author A0099655J
	public static WritableSheet writeLogDataToSheet(WritableSheet sheet,
			WritableCellFormat format, int i,
			String timestamp_str, String operation) throws WriteException,
			RowsExceededException {
		
		// Write to xls sheet
		
		Label l;
		l = new Label(0,i, timestamp_str, format);
		sheet.addCell(l);
		l = new Label(1,i, operation, format);
		sheet.addCell(l);

		return sheet;
	}

	//@author A0099655J
	public static WritableSheet writeTasksToSheet(WritableSheet sheet,
			WritableCellFormat format, int i, int j,
			boolean completed, String startDateTime_str, String endDateTime_str, String desc) throws WriteException,
			RowsExceededException {
		
		// Write to xls sheet
		
		Label l;
		l = new Label(j,i, String.valueOf(completed), format);
		sheet.addCell(l);
		l = new Label(j+1,i, startDateTime_str, format);
		sheet.addCell(l);
		l = new Label(j+2,i, endDateTime_str, format);
		sheet.addCell(l);
		l = new Label(j+3,i, desc, format);
		sheet.addCell(l);
		

		return sheet;
	}
}
